#include "peripheral_uart.h"
#include "utils_log.h"
#include "common_config_manager.h"
#include <vector>

namespace El {
namespace Peripheral {

// ============================================================================
// UartManager 实现
// ============================================================================

UartManager &UartManager::GetInstance()
{
    static UartManager instance;
    return instance;
}

UartManager::UartManager() {}

UartManager::~UartManager()
{
    DeinitAll();
}

bool UartManager::Start()
{
    // 从配置中获取串口设置
    auto uart_config = El::Common::ConfigManager::GetInstance().GetConfig("/uart");
    if (uart_config.is_null()) {
        EL_ERROR("UART configuration not found");
        return false;
    }

    int32_t success_count = 0;
    int32_t total_count = 0;

    // 遍历所有串口配置
    for (auto &[uart_name, uart_settings] : uart_config.items()) {
        // 跳过全局配置
        if (uart_name == "global") {
            continue;
        }

        total_count++;

        // 检查是否启用该串口
        if (!uart_settings.contains("enabled") || !uart_settings["enabled"].is_boolean()) {
            EL_WARN("UART {} enable flag not configured properly, skipping", uart_name);
            continue;
        }

        if (!uart_settings["enabled"].get<bool>()) {
            EL_INFO("UART {} is disabled, skipping", uart_name);
            continue;
        }

        // 获取串口设备路径
        if (!uart_settings.contains("port") || !uart_settings["port"].is_string()) {
            EL_ERROR("UART {} device path not configured properly", uart_name);
            continue;
        }

        std::string dev_path = uart_settings["port"].get<std::string>();

        // 设置串口属性
        UART_ATTR attr;

        // 设置波特率
        attr.baudrate = uart_settings.value("baudRate", 115200);

        // 设置数据位
        attr.databits = uart_settings.value("dataBits", 8);

        // 设置校验位
        std::string parity = uart_settings.value("parity", "none");
        if (parity == "none") {
            attr.parity = UART_NOPARITY;
        } else if (parity == "odd") {
            attr.parity = UART_ODDPARITY;
        } else if (parity == "even") {
            attr.parity = UART_EVENPARITY;
        } else {
            attr.parity = UART_NOPARITY;
        }

        // 设置停止位
        uint8_t stopbits = uart_settings.value("stopBits", 1);
        if (stopbits == 1) {
            attr.stopbits = UART_ONESTOPBIT;
        } else if (stopbits == 2) {
            attr.stopbits = UART_TWOSTOPBITS;
        } else {
            attr.stopbits = UART_ONESTOPBIT;
        }

        // 获取阻塞模式
        bool block_mode = true;
        if (uart_settings.contains("blockMode") && uart_settings["blockMode"].is_boolean()) {
            block_mode = uart_settings["blockMode"].get<bool>();
        }

        // 初始化串口设备
        int32_t ret = InitUart(uart_name, dev_path, block_mode);
        if (ret < 0) {
            EL_ERROR("Failed to initialize UART {}: {}", uart_name, dev_path);
            continue;
        }

        // 应用串口属性
        ret = SetUartAttribute(uart_name, attr);
        if (ret < 0) {
            EL_ERROR("Failed to set UART {} attributes, ret: {}", uart_name, ret);
            continue;
        }

        success_count++;
        EL_INFO("UART {} initialized successfully: {}, baudrate: {}, databits: {}", uart_name, dev_path, attr.baudrate,
                 attr.databits);
    }

    EL_INFO("UART initialization completed: {}/{} successful", success_count, total_count);
    return true;
}

int32_t UartManager::InitUart(const std::string &name, const std::string &dev, bool block)
{
    // 如果已存在，先关闭
    if (uartDevices_.find(name) != uartDevices_.end()) {
        DeinitUart(name);
    }

    // 创建新的串口设备信息
    auto uart_info = std::make_unique<UartDeviceInfo>();
    uart_info->com = std::make_unique<Com>();
    uart_info->devPath = dev;
    uart_info->blockMode = block;

    int32_t ret = uart_info->com->Create(dev.c_str(), block);
    if (ret < 0) {
        EL_ERROR("Failed to initialize UART {}: {}", name, dev);
        return ret;
    }

    uartDevices_[name] = std::move(uart_info);
    EL_INFO("UART {} initialized: {}", name, dev);
    return 0;
}

Com *UartManager::GetUart(const std::string &name)
{
    auto it = uartDevices_.find(name);
    if (it != uartDevices_.end()) {
        return it->second->com.get();
    }
    return nullptr;
}

UartDeviceInfo *UartManager::GetUartInfo(const std::string &name)
{
    auto it = uartDevices_.find(name);
    if (it != uartDevices_.end()) {
        return it->second.get();
    }
    return nullptr;
}

int32_t UartManager::SetUartAttribute(const std::string &name, const UART_ATTR &attr)
{
    Com *uart_com = GetUart(name);
    if (!uart_com) {
        EL_ERROR("UART {} not found", name);
        return -1;
    }

    UART_ATTR mutable_attr = attr; // 创建可修改的副本
    int32_t ret = uart_com->SetAttribute(&mutable_attr);
    if (ret < 0) {
        EL_ERROR("Failed to set UART {} attributes", name);
        return ret;
    }

    // 设置成功后，保存配置到配置管理器
    auto uart_config = El::Common::ConfigManager::GetInstance().GetConfig("/uart");
    if (!uart_config.is_null() && uart_config.contains(name)) {
        // 更新配置中的属性值，使用驼峰命名
        uart_config[name]["baudRate"] = attr.baudrate;
        uart_config[name]["dataBits"] = attr.databits;

        // 保存校验位
        std::string parity;
        switch (attr.parity) {
            case UART_NOPARITY:
                parity = "none";
                break;
            case UART_ODDPARITY:
                parity = "odd";
                break;
            case UART_EVENPARITY:
                parity = "even";
                break;
            default:
                parity = "none";
                break;
        }
        uart_config[name]["parity"] = parity;

        // 保存停止位
        uint8_t stopbits;
        switch (attr.stopbits) {
            case UART_ONESTOPBIT:
                stopbits = 1;
                break;
            case UART_TWOSTOPBITS:
                stopbits = 2;
                break;
            default:
                stopbits = 1;
                break;
        }
        uart_config[name]["stopBits"] = stopbits;

        // 保存配置
        EL_INFO("UART {} attributes saved to config", name);
        El::Common::ConfigManager::GetInstance().SetConfig("/uart", uart_config);
    }

    return 0;
}

int32_t UartManager::DeinitUart(const std::string &name)
{
    auto it = uartDevices_.find(name);
    if (it != uartDevices_.end()) {
        int32_t ret = it->second->com->Delete();
        uartDevices_.erase(it);
        EL_INFO("UART {} deinitialized", name);
        return ret;
    }
    return 0;
}

int32_t UartManager::DeinitAll()
{
    for (auto &[name, device_info] : uartDevices_) {
        device_info->com->Delete();
        EL_INFO("UART {} deinitialized", name);
    }
    uartDevices_.clear();
    return 0;
}

std::vector<std::string> UartManager::GetInitializedUarts() const
{
    std::vector<std::string> names;
    for (const auto &[name, device_info] : uartDevices_) {
        names.push_back(name);
    }
    return names;
}

bool UartManager::IsUartInitialized(const std::string &name) const
{
    return uartDevices_.find(name) != uartDevices_.end();
}

std::string UartManager::GetUartDevicePath(const std::string &name) const
{
    auto it = uartDevices_.find(name);
    if (it != uartDevices_.end()) {
        return it->second->devPath;
    }
    return "";
}

} // namespace Peripheral
} // namespace El
